package com.nativetalk.service.three.reserve.update;

import com.nativetalk.base.RetInfo;
import com.nativetalk.bean.Bill;
import com.nativetalk.bean.FoundChange.TdNtMembFoundChangeInset;
import com.nativetalk.bean.FoundChange.TdNtTeaFoundChangeInsert;
import com.nativetalk.bean.member.TdNtMemberDetail;
import com.nativetalk.bean.member.TdNtMemberInvite;
import com.nativetalk.bean.member.setmeal.TdNtMembSetmealDetail;
import com.nativetalk.bean.reserve.TdNtReserveInsert;
import com.nativetalk.bean.reserve.TdNtReserveTimeDetail;
import com.nativetalk.bean.sms.Sms;
import com.nativetalk.bean.teacher.TdNtTeacherGetui;
import com.nativetalk.bean.teacher.TdNtTeacherIndex;
import com.nativetalk.common.*;
import com.nativetalk.common.getui.AndroidReserveTeacher;
import com.nativetalk.common.getui.IosReserveTeacher;
import com.nativetalk.common.util.CommonUtil;
import com.nativetalk.common.util.DateUtil;
import com.nativetalk.common.util.OrderUtil;
import com.nativetalk.common.util.SMSUtil;
import com.nativetalk.dao.*;
import org.apache.log4j.Logger;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

/**
 * Created by lizhun on 16/7/21.
 */
@Service
public class ThreeReserveUpdateServiceImpl implements ThreeReserveUpdateService {
    private static Logger logger = Logger.getLogger(ThreeReserveUpdateServiceImpl.class);
    @Resource
    private TdNtReserveDao tdNtReserveDao;
    @Resource
    private TdNtMemberDao tdNtMemberDao;
    @Resource
    private TdNtMembFoundChangeDao tdNtMembFoundChangeDao;
    @Resource
    private TdNtTeacherDao tdNtTeacherDao;
    @Resource
    private TdNtTeaFoundChangeDao tdNtTeaFoundChangeDao;
    @Resource
    private TdNtReserveTimeDao tdNtReserveTimeDao;
    @Resource
    private TdNtMembSetmealDao tdNtMembSetmealDao;
    @Resource
    private BillDao billDao;

    @Override
    @Transactional
    public RetInfo cancelByMembId(int reserve_id) {
        String logInfo = this.getClass().getName() + ":cancelByMembId:";
        // 类路径+方法名
        logger.info("======" + logInfo + "begin======");
        RetInfo retInfo = new RetInfo();
        try {
            TdNtReserveInsert tdNtReserve = tdNtReserveDao.findTdNtReserverById(reserve_id);
            if (tdNtReserve == null) {
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("无效的预约");
                return retInfo;
            }
            if (Constants.ReserveState.finished == tdNtReserve.getState()) {
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("已完成的预约不能取消");
                return retInfo;
            }
            if (Constants.ReserveState.canceled == tdNtReserve.getState()) {
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("预约已取消");
                return retInfo;
            }

            // 一小时内不能取消
            if (!CommonUtil.getTimeCancle(tdNtReserve.getReserve_start_time())) {
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("开始前一个小时不能取消预约");
                return retInfo;
            }

            if (Constants.ReserveType.listen_course == tdNtReserve.getType()) {
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("试听课无法取消预约");
                return retInfo;
            }

            // 4小时内取消预约扣除20元手续费
            if (!CommonUtil.getTimeResult(tdNtReserve.getReserve_start_time())) {
                BigDecimal memb_balance = tdNtMemberDao.findTdNtMemberBalabce(tdNtReserve.getMemb_id());
                BigDecimal amount = new BigDecimal(20);
                if (memb_balance.compareTo(amount) < 0) {
                    retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                    retInfo.setTip("取消预约失败。余额不足20元。（4小时内取消预约扣除20元手续费）");
                    return retInfo;
                } else {
                    // 扣除20元手续费
                    serviceCharge(tdNtReserve, memb_balance, amount);
                }
            }

            TdNtMembSetmealDetail membSetmeal = tdNtMembSetmealDao.fidById(tdNtReserve.getMemb_set_id());
            if (membSetmeal == null) {
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("取消失败：无效套餐id=" + tdNtReserve.getMemb_set_id());
                logger.error("取消失败：无效套餐id=" + tdNtReserve.getMemb_set_id() + ",reserveId=" + tdNtReserve.getReserve_id());
                return retInfo;
            }

            // 1. 更新预约的状态
            tdNtReserve.setState(Constants.ReserveState.canceled);//已取消状态
            tdNtReserveDao.updateTdNtReserve(tdNtReserve);

            // 2. 更新老师的预约时间状态
            TdNtReserveTimeDetail tdNtReserveTimeDetail = new TdNtReserveTimeDetail();
            tdNtReserveTimeDetail.setTea_id(tdNtReserve.getTea_id());
            tdNtReserveTimeDetail.setReserve_time(CommonUtil.getHour(tdNtReserve.getReserve_start_time()));
            tdNtReserveTimeDetail.setDate(tdNtReserve.getReserve_start_time());
            tdNtReserveTimeDetail.setIs_valid(Constants.ReserveTimeState.open);
            tdNtReserveTimeDao.updateTdNtReserveTimeSetIsValidForWeekly(tdNtReserveTimeDetail);

            // 3. 学生购买的套餐的可以预约次数+1
            Map<String, Object> map2 = new HashMap<>();
            map2.put("memb_set_id", membSetmeal.getMemb_set_id());
            map2.put("set_reserve_size", membSetmeal.getSet_reserve_size() + 1);
            tdNtMembSetmealDao.updateTdNtMembSetmealDetailEnd(map2);

            TdNtTeacherGetui teacher = tdNtTeacherDao.findTdNtTeacher(tdNtReserve.getTea_id());

            // 4. 给教师发推送
            try {
                sendNotifyToTeacher(tdNtReserve, teacher);
            } catch (Exception e) {
                logger.error("邮件或推送发送失败", e);
            }

            // 5. 给学生发短信
            try {
                TdNtMemberDetail member = tdNtMemberDao.findTdNtMemberDetail(tdNtReserve.getMemb_id());
                logger.info("发送短信 start\n 手机号：" + member.getMemb_phone_area() + "-" + member.getMemb_phone());
                Sms sms = new Sms(member.getMemb_phone(), member.getMemb_phone_area());
                String content = "【外教君】 您已取消预约";
                String startTime = DateUtil.format(tdNtReserve.getReserve_start_time(), "yyyy-MM-dd HH:mm");
                String endTime = DateUtil.format(tdNtReserve.getReserve_end_time(), "yyyy-MM-dd HH:mm");
                content += "，预约时间：" + startTime + " 至 " + endTime;
                SMSUtil.sendSms(sms, content);
                logger.info("发送短信 end");
            } catch (Exception e) {
                logger.error("短信发送失败", e);
            }

            retInfo.setMark(ValidationMessages.getValue("MARKYES"));
            retInfo.setTip("取消成功");
        } catch (Exception e) {
            retInfo.setMark(ValidationMessages.getValue("MARKERROR"));
            retInfo.setTip(ValidationMessages.getValue("TIPERROR"));
            logger.error(e.getMessage(), e);
        }
        logger.info("======" + logInfo + "end======");
        return retInfo;
    }

    private void sendNotifyToTeacher(TdNtReserveInsert tdNtReserve, TdNtTeacherGetui teacher) {
        if (teacher.getEqu_client_id() != null) {
            //  发推送
            try {
                String title = "NativeTalk";
                String body = "Dear NativeTalk tutor, cancel assignment class.\n ";
                logger.info("发推送，取消预约 deviceType=" + teacher.getEqu_type() + ",  deviceId=" + teacher.getEqu_client_id());
                if (teacher.getEqu_type().equals(Constants.equ_type_android)) {
                    AndroidReserveTeacher.apnpush(title, body, teacher.getEqu_client_id(), tdNtReserve.getReserve_id());
                } else {
                    IosReserveTeacher.apnpush(title, body, teacher.getEqu_client_id(), tdNtReserve.getReserve_id());
                }
            } catch (Exception e) {
                logger.error("推送发送失败", e);
            }

        }
    }

    private void serviceCharge(TdNtReserveInsert tdNtReserve, BigDecimal memb_balance, BigDecimal amount) {
        // 添加账单
        Bill bill = new Bill();
        bill.setActionType(PaymentConstants.ActionType.IN);
        bill.setActionName(GoodsCategory.APPOINTMENT_CANCEL.getName());
        bill.setActionIconUrl(GoodsCategory.APPOINTMENT_CANCEL.getIcon());
        bill.setGoodsCategoryCode(GoodsCategory.APPOINTMENT_CANCEL.getCode());
        bill.setGoods_desc("取消预约");
        bill.setPaymentStatus(PaymentConstants.Status.SUCCESS);
        bill.setPayMoney(new BigDecimal(0));
        bill.setPayType(PayType.system.getName());
        bill.setChannel(PaymentConstants.Channel.system);
        bill.setCreateOrderTime(new Date());
        bill.setOrderNo(OrderUtil.getOrderNumber());// 订单号（交易单号）

        bill.setAmount(amount);
        bill.setBalanceBefore(memb_balance);
        bill.setBalanceChange(amount);
        bill.setBalanceAfter(memb_balance.subtract(amount));
        bill.setMembId(tdNtReserve.getMemb_id());
        billDao.insert(bill);

        // 更新学生余额
        memb_balance = memb_balance.subtract(amount);
        TdNtMemberInvite tdNtMemberInvite = new TdNtMemberInvite();
        tdNtMemberInvite.setMemb_balance(memb_balance);
        tdNtMemberInvite.setMemb_id(tdNtReserve.getMemb_id());
        tdNtMemberDao.updateTdNtMemberBalance(tdNtMemberInvite);
    }


    @Override
    public RetInfo cancelTeaId(int reserve_id) {
        String logInfo = this.getClass().getName() + ":cancelTeaId:";
        // 类路径+方法名
        logger.info("======" + logInfo + "begin======");
        RetInfo retInfo = new RetInfo();
        try {
            TdNtReserveInsert tdNtReserve = tdNtReserveDao.findTdNtReserverById(reserve_id);
            if (tdNtReserve != null && Constants.ReserveState.ready_to_begin == tdNtReserve.getState()) {
                /**
                 * 一小时内不能取消
                 */
                if (!CommonUtil.getTimeCancle(tdNtReserve.getReserve_start_time())) {
                    retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                    retInfo.setTip("开课前一小时不能取消");
                    return retInfo;
                }
                tdNtReserve.setState(Constants.ReserveState.canceled);
                tdNtReserveDao.updateTdNtReserve(tdNtReserve);
                BigDecimal memb_balance = tdNtMemberDao.findTdNtMemberBalabce(tdNtReserve.getMemb_id());

                /**
                 * 添加资金变动记录
                 */
                TdNtMembFoundChangeInset tdNtMembFoundChangeInset = new TdNtMembFoundChangeInset();

                tdNtMembFoundChangeInset.setMemb_id(tdNtReserve.getMemb_id());
                tdNtMembFoundChangeInset.setMfchg_change_month(CommonUtil.getMonth(new Date()));
                tdNtMembFoundChangeInset.setMfchg_back_amount(memb_balance.add(tdNtReserve.getAmout()));
                tdNtMembFoundChangeInset.setMfchg_change_amount(tdNtReserve.getAmout());
                tdNtMembFoundChangeInset.setMfchg_change_name("取消预约");
                tdNtMembFoundChangeInset.setMfchg_change_type(Constants.FundChangeType.wallet_out);
                tdNtMembFoundChangeInset.setMfchg_front_amount(memb_balance);
                tdNtMembFoundChangeInset.setState(Constants.PayState.success);
                tdNtMembFoundChangeInset.setType(Constants.ChargeType.cancel_reserver_code);
                tdNtMembFoundChangeInset.setMfchg_number(CommonUtil.getOrderNub());

                tdNtMembFoundChangeDao.insertTdNtMembFoundChange(tdNtMembFoundChangeInset);

                memb_balance = tdNtMembFoundChangeInset.getMfchg_back_amount();

                TdNtMemberInvite tdNtMemberInvite = new TdNtMemberInvite();
                tdNtMemberInvite.setMemb_balance(memb_balance);
                tdNtMemberInvite.setMemb_id(tdNtReserve.getMemb_id());
                tdNtMemberDao.updateTdNtMemberBalance(tdNtMemberInvite);
                //扣除老师手续费 更新老师余额
                //判断是否为自由话题
                BigDecimal changeAmount = new BigDecimal(5);
//                if (tdNtReserve.getCou_id() == 100) {
//                    changeAmount = tdNtTeacherDao.findTdNtTeacherMiuAmount(tdNtReserve.getTea_id()).multiply(new BigDecimal(tdNtReserve.getReserve_time())).multiply(new BigDecimal(0.2));
//                } else {
//                    Map<String,TwoTsNtCourseInfoDetail> tsNtCourseInfoDetailMapTwo  = (Map<String, TwoTsNtCourseInfoDetail>) MemcachedUtils.get(MemcachedKey.tsNtCourseInfoDetailMapTwo);
//                    Map<String, TsNtSetmealIndex> tsNtSetmealSynopisMap = (Map<String, TsNtSetmealIndex>) MemcachedUtils.get(MemcachedKey.tsNtSetmealIndexMap);
//                    String cate_id = tsNtCourseInfoDetailMapTwo.get(tdNtReserve.getCou_id() + "").getCate_id().toString();
//                    TsNtSetmealIndex setmealIndex = tsNtSetmealSynopisMap.get(cate_id);
//                    changeAmount = setmealIndex.getSet_amout().divide(
//                            new BigDecimal(setmealIndex.getSet_time()),2, BigDecimal.ROUND_HALF_EVEN).multiply(new BigDecimal(tdNtReserve.getReserve_time()).multiply(new BigDecimal(0.2)));
//                }
                /**
                 * 添加教师资金变动记录
                 */
                TdNtTeacherIndex tdNtTeacherIndex = tdNtTeacherDao.findTdNtTeacherIndex(tdNtReserve.getTea_id());

                TdNtTeaFoundChangeInsert tdNtTeaFoundChangeInsert = new TdNtTeaFoundChangeInsert();
                tdNtTeaFoundChangeInsert.setState("2");
                tdNtTeaFoundChangeInsert.setTea_id(tdNtReserve.getTea_id());
                tdNtTeaFoundChangeInsert.setTfchg_account(new BigDecimal("0"));
                tdNtTeaFoundChangeInsert.setTfchg_change_amount(changeAmount);
                tdNtTeaFoundChangeInsert.setTfchg_back_amount(tdNtTeacherIndex.getTea_balance().subtract(changeAmount));
                tdNtTeaFoundChangeInsert.setTfchg_change_month(CommonUtil.getMonth(new Date()));
                tdNtTeaFoundChangeInsert.setTfchg_change_type("2");
                tdNtTeaFoundChangeInsert.setTfchg_counter_fee(new BigDecimal("0"));
                tdNtTeaFoundChangeInsert.setTfchg_front_amount(tdNtTeacherIndex.getTea_balance());
                tdNtTeaFoundChangeInsert.setTfchg_number(CommonUtil.getOrderNub());
                tdNtTeaFoundChangeInsert.setTfchg_change_name("Liquidated damages");
                tdNtTeaFoundChangeDao.insertTdNtTeaFoundChangeInsert(tdNtTeaFoundChangeInsert);
                tdNtTeacherIndex.setTea_balance(tdNtTeaFoundChangeInsert.getTfchg_back_amount());
                tdNtTeacherDao.updateTdNtTeacherIndex(tdNtTeacherIndex);
                retInfo.setMark(ValidationMessages.getValue("MARKYES"));
                retInfo.setTip("取消成功");
            } else {
                retInfo.setMark(ValidationMessages.getValue("MARKNO"));
                retInfo.setTip("预约订单不存在或已取消");
            }

        } catch (Exception e) {
            retInfo.setMark(ValidationMessages.getValue("MARKERROR"));
            retInfo.setTip(ValidationMessages.getValue("TIPERROR"));
            logger.error(e.getMessage(), e);
        }
        logger.info("======" + logInfo + "end======");
        return retInfo;
    }


}
